package com.yict.csms.resourceplan.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.yict.common.Constants;
import com.yict.common.entity.PageEntity;
import com.yict.common.service.impl.BaseServiceImpl;
import com.yict.common.util.DateUtil;
import com.yict.common.util.ObjectUtil;
import com.yict.csms.baseInfo.entity.PerOrderSetLine;
import com.yict.csms.baseInfo.entity.PersonOrderSet;
import com.yict.csms.baseInfo.service.IPerOrderSetLineService;
import com.yict.csms.company.entity.ContractRate;
import com.yict.csms.company.service.impl.ContractRateServiceImpl;
import com.yict.csms.resourceplan.dao.IPersonOrderDao;
import com.yict.csms.resourceplan.entity.PersonOrder;
import com.yict.csms.resourceplan.service.IPersonOrderService;
import com.yict.csms.system.entity.DataDict;
import com.yict.csms.system.entity.User;
import com.yict.csms.system.entity.UserDataper;
import com.yict.csms.system.service.ICostService;
import com.yict.csms.system.service.IDataDictService;
import com.yict.csms.system.service.impl.UserServiceImpl;
import com.yict.csms.system.util.DictionaryUtils;

@Service("personOrderService")
public class PersonOrderServiceImpl extends BaseServiceImpl<PersonOrder, Long, IPersonOrderDao> implements IPersonOrderService {

	private IDataDictService dictservice;
	private ICostService costService;
	private UserServiceImpl csi;
	private IPerOrderSetLineService perOrderSetLineService;
	private ContractRateServiceImpl contractRateService;

	@Override
	public List<PersonOrder> listByIds(Collection<Long> ids) {
		if (ids == null || ids.size() == 0)
			return new ArrayList<PersonOrder>();
		String hql = "from PersonOrder p where orderid in (:orderid)";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orderid", ids);
		List<PersonOrder> list;
		try {
			list = getBaseDao().list(hql, map, 0, 0);
		} catch (Exception e) {
			list = new ArrayList<PersonOrder>();
		}
		return list;
	}
	
	@Override
	@Transactional(readOnly = false)
	public boolean remove(Long[] ids,Long userid) throws Exception {
		DataDict dataDict = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_1);
		User us = csi.findById(userid);
		Set<UserDataper> usSet = us.getUserDataperSet();
		Set<Long> dpids = new HashSet<Long>();
		for(UserDataper ud : usSet)
			dpids.add(ud.getDataper().getCwtId());
		
		for(Long id : ids){
			PersonOrder po = getBaseDao().findbyId(id);
			if(!(po.getStatus() == null || dataDict.getDictid().equals(po.getStatus()))) 
				throw new Exception("不能删除当前状态下的记录！");
			if(!dpids.contains(po.getCwtid()))
				throw new Exception("没有操作权限！");
		}
		super.remove(ids);
		return true;
	}

	@Override
	@Transactional(readOnly = false)
	public boolean save(PersonOrder t) throws Exception {
		List<ContractRate> list = contractRateService.listPersonOrder(t.getCompanyid(), t.getProfeid(), t.getOrderdate());
		if(list.size() == 0) throw new Exception("没有找到合同费率");
		return super.save(t);
	}

	@Override
	@Transactional(readOnly = false)
	public boolean update(PersonOrder t) throws Exception {
		List<ContractRate> list = contractRateService.listPersonOrder(t.getCompanyid(), t.getProfeid(), t.getOrderdate());
		if(list.size() == 0) throw new Exception("没有找到合同费率");
		DataDict status = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_1);
		PersonOrder vo = this.findById(t.getOrderid());
		if(vo == null) throw new Exception("数据已经被删除！");
		if(!status.getDictid().equals(vo.getStatus()))throw new Exception("只能修改未定更的数据！");
		vo.setCwtid(t.getCwtid());
		vo.setOrderdate(t.getOrderdate());
		vo.setOrdertime(t.getOrdertime());
		vo.setProfeid(t.getProfeid());
		vo.setStationid(t.getStationid());
		vo.setCompanyid(t.getCompanyid());
		vo.setInputtype(t.getInputtype());
		vo.setUnit(t.getUnit());
		vo.setOrderquantity(t.getOrderquantity());
		vo.setOrderdoquan(t.getOrderdoquan());
		vo.setAllorderquan(t.getAllorderquan());
		vo.setOrderbegindate(t.getOrderbegindate());
		vo.setOrderenddate(t.getOrderenddate());
		vo.setRemovalreason(t.getRemovalreason());
		vo.setRemovaltime(t.getRemovaltime());
		vo.setUpdatedate(t.getUpdatedate());
		
		/*//默认派更数据
		vo.setWorkquantity(t.getOrderquantity());
		vo.setWorkdoquan(t.getOrderdoquan());
		vo.setWorkbegindate(t.getOrderbegindate());
		vo.setWorkenddate(t.getOrderenddate());
		vo.setAllworkquan(t.getAllorderquan());*/
		return true;
	}

	@Override
	@Transactional(readOnly = false)
	public boolean update1(PersonOrder t) throws Exception {
		DataDict status = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_2);
		PersonOrder vo = this.findById(t.getOrderid());
		if(!status.getDictid().equals(vo.getStatus()))throw new Exception("只能修改已定更的数据！");
		vo.setWorkquantity(t.getWorkquantity());
		vo.setWorkdoquan(t.getWorkdoquan());
		vo.setWorkbegindate(t.getWorkbegindate());
		vo.setWorkenddate(t.getWorkenddate());
		vo.setAllworkquan(t.getAllworkquan());
		
		return true;
	}

	@Override
	@Transactional(readOnly = false,rollbackFor = {Exception.class})
	public boolean submit0(Long[] ids, Long userId) throws Exception {
		Date taday = new Date();
		DataDict dataDict = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_2);
		DataDict dataDictNow = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_1);;
		int i = 1;
		for(Long id : ids){
			PersonOrder vo = getBaseDao().findbyId(id);
			if(!dataDictNow.getDictid().equals(vo.getStatus()))
//				throw new Exception("第" + i + "条记录状态不是" + dataDictNow.getDisplayname());
				throw new Exception("记录状态不是" + dataDictNow.getDisplayname());
			vo.setOrderperson(userId);
			vo.setOrderbydate(taday);
			vo.setStatus(dataDict.getDictid());
			
			//默认派更数据
			vo.setWorkquantity(vo.getOrderquantity());
			vo.setWorkdoquan(vo.getOrderdoquan());
			vo.setWorkbegindate(vo.getOrderbegindate());
			vo.setWorkenddate(vo.getOrderenddate());
			vo.setAllworkquan(vo.getAllorderquan());
			i += 1;
			//getBaseDao().update(vo);
		}
		return true;
	}
	
	@Override
	@Transactional(readOnly = false,rollbackFor = {Exception.class})
	public boolean submit1(Long[] ids, Long userId) throws Exception {
		Date taday = new Date();
		DataDict dataDict = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_3);
		DataDict dataDictNow = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_2);;
		int i = 1;
		for(Long id : ids){
			PersonOrder vo = getBaseDao().findbyId(id);
			if(!dataDictNow.getDictid().equals(vo.getStatus()))
//				throw new Exception("第" + i + "条记录状态不是" + dataDictNow.getDisplayname());
				throw new Exception("记录状态不是" + dataDictNow.getDisplayname());
			vo.setAssignedperson(userId);
			vo.setAssigneddate(taday);
			vo.setStatus(dataDict.getDictid());
			i += 1;
			//getBaseDao().update(vo);
		}
		return true;
	}
	
	@Override
	@Transactional(readOnly = false,rollbackFor = {Exception.class})
	public boolean reject0(Long[] ids, Long userId) throws Exception {
		DataDict dataDict = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_1);
		DataDict dataDictNow = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_2);;
		int i = 1;
		for(Long id : ids){
			PersonOrder vo = getBaseDao().findbyId(id);
			if(!dataDictNow.getDictid().equals(vo.getStatus()))
//				throw new Exception("第" + i + "条记录状态不是" + dataDictNow.getDisplayname());
				throw new Exception("记录状态不是" + dataDictNow.getDisplayname());
			vo.setStatus(dataDict.getDictid());
			i += 1;
			//getBaseDao().update(vo);
		}
		return true;
	}

	@Override
	@Transactional(readOnly = false,rollbackFor = {Exception.class})
	public boolean submit2(Long[] ids, Long userId) throws Exception {
		Date taday = new Date();
		DataDict dataDict = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_4);
		DataDict dataDictNow = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_3);
		int i = 1;
		User us = csi.findById(userId);
		if(us == null) throw new Exception("无法获取当前用户！");
		DataDict amDict1 = dictservice.findByCode(DictionaryUtils.DICT_CODE_ACCOUNTMETHOD_1);
		DataDict amDict2 = dictservice.findByCode(DictionaryUtils.DICT_CODE_ACCOUNTMETHOD_2);
		
		for(Long id : ids){
			PersonOrder vo = getBaseDao().findbyId(id);
			if(!dataDictNow.getDictid().equals(vo.getStatus()))
//				throw new Exception("第" + i + "条记录状态不是" + dataDictNow.getDisplayname());
				throw new Exception("记录状态不是" + dataDictNow.getDisplayname());
			vo.setAssignedperson(userId);
			vo.setAssigneddate(taday);
			vo.setStatus(dataDict.getDictid());

			BigDecimal number;
			//计费数据来源
			DataDict fromDict = dictservice.findByCode(DictionaryUtils.DICT_CODE_COST_SOURCE_5);
			//订更计费类型与工种计费类型转换
			String accountmethod;
			DataDict itDict = dictservice.findById(vo.getInputtype());
			if(DictionaryUtils.DICT_CODE_INPUT_TYPE1.equals(itDict.getDatacode())){
				accountmethod = amDict1.getDictid();
				number = vo.getWorkquantity();
			}else{
				accountmethod = amDict2.getDictid();
				number = vo.getWorkdoquan();
			}
			//生成计费记录
			costService.createCost(vo.getCompanyid(), vo.getProfeid(), vo.getStationid(), 
					vo.getOrderid(), accountmethod, vo.getOrderdate(), vo.getWorkbegindate(), 
					vo.getWorkenddate(), vo.getOrdertime(), vo.getRemovaltime(), vo.getRemovalreason(), 
					number, fromDict.getDictid(), us);
			i += 1;
			//getBaseDao().update(vo);
		}
		return true;
	}

	@Override
	@Transactional(readOnly = false,rollbackFor = {Exception.class})
	public boolean reject1(Long[] ids, Long userId) throws Exception {
		DataDict dataDict = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_2);
		DataDict dataDictNow = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_3);;
		int i = 1;
		for(Long id : ids){
			PersonOrder vo = getBaseDao().findbyId(id);
			if(!dataDictNow.getDictid().equals(vo.getStatus()))
//				throw new Exception("第" + i + "条记录状态不是" + dataDictNow.getDisplayname());
				throw new Exception("记录状态不是" + dataDictNow.getDisplayname());
			vo.setStatus(dataDict.getDictid());
			i += 1;
			//getBaseDao().update(vo);
		}
		return true;
	}
	
	@Override
	//@Transactional(readOnly = false,rollbackFor = {Exception.class})
	public boolean reject2(Long[] ids, Long userId) throws Exception {
		DataDict dataDict = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_3);
		DataDict dataDictNow = dictservice.findByCode(DictionaryUtils.ORDER_STATUS_4);;
		int i = 1;
		for(Long id : ids){
			PersonOrder vo = getBaseDao().findbyId(id);
			if(!dataDictNow.getDictid().equals(vo.getStatus()))
//				throw new Exception("第" + i + "条记录状态不是" + dataDictNow.getDisplayname());
				throw new Exception("记录状态不是" + dataDictNow.getDisplayname());
			vo.setStatus(dataDict.getDictid());
			i += 1;
			//getBaseDao().update(vo);
		}
		return true;
	}

	@Override
	@Transactional(readOnly = false, rollbackFor = { Exception.class })
	public boolean importAsTempl(PersonOrderSet pos) throws Exception {
		Map<String, Object> queryMap = new HashMap<String, Object>();
		queryMap.put("personOrderSet.setid", pos.getSetid());
		List<PerOrderSetLine> poslList = perOrderSetLineService.list(queryMap, null, null);

		Date orderDate = null;
		String current = DateUtil.DateToString(new Date(), 1);
		DataDict nextOrderTime = dictservice.findNextShiftTime(new Date(), true);
		if (nextOrderTime.getDisplayname().equals("C")) {
			orderDate = DateUtil.getNextDate(current);
		} else {
			orderDate = DateUtil.StringToDate(current, 1);
		}
		// 状态默认为未订更
		DataDict status = dictservice.findByCode("Order_status_1");
		if (status == null || status.getDisplayname() == null) {
			throw new Exception("查询数据字典出错");
		}
		// 模式默认为计划
		DataDict mode = dictservice.findByCode("Order_method_1");
		if (mode == null || mode.getDisplayname() == null) {
			throw new Exception("查询数据字典出错");
		}

		for (PerOrderSetLine posl : poslList) {
			PersonOrder po = new PersonOrder();
			PropertyUtils.copyProperties(po, posl);
			po.setOrdertime(nextOrderTime.getDictid());
			po.setCwtid(pos.getCwtid());
			po.setOrderdate(orderDate);
			// 预订开始时间
			String beginDateStr = DateUtil.DateToString(orderDate, 1) + " "
					+ DateUtil.DateToString(posl.getOrderbegindate(), 9);
			po.setOrderbegindate(DateUtil.StringToDate(beginDateStr, 2));
			// 预订结束时间
			String endDateStr = DateUtil.DateToString(orderDate, 1) + " "
					+ DateUtil.DateToString(posl.getOrderenddate(), 9);
			po.setOrderenddate(DateUtil.StringToDate(endDateStr, 2));
			po.setStatus(status.getDictid());
			po.setTmode(mode.getDictid());
			super.save(po);
		}

		return true;
	}
	

	@Override
	public void exportAsTempl(PersonOrderSet pos, Collection<Long> ids) throws Exception {
		for (Long id : ids) {
			PersonOrder po = getBaseDao().findbyId(id);
			PerOrderSetLine setLine = new PerOrderSetLine();
			PropertyUtils.copyProperties(setLine, po);
			setLine.setPersonOrderSet(pos);
			//	仅保留小时、分钟.
			String beginDate = DateUtil.format(setLine.getOrderbegindate(), "hh:mm");
			setLine.setOrderbegindate(DateUtil.parse(beginDate, "hh:mm"));
			String endDate = DateUtil.format(setLine.getOrderenddate(), "hh:mm");
			setLine.setOrderenddate(DateUtil.parse(endDate, "hh:mm"));
			
			perOrderSetLineService.save(setLine);
		}
	}

	@Override
	public List<PersonOrder> list(Map<String, Object> queryMap,
			PageEntity page, LinkedHashMap<String, Boolean> orderList) {
		List<PersonOrder> list = new ArrayList<PersonOrder>();
		StringBuilder hql = new StringBuilder("from PersonOrder where 1 = 1"); 
		Map<String, Object> coditionMap = new HashMap<String, Object>();
		if(queryMap != null){
			Object fromdateObj = queryMap.get("fromdate");
			Date fromdate = null;
			if(fromdateObj instanceof Date){
				fromdateObj = ObjectUtil.d2s(((Date)fromdateObj), "yyyy-MM-dd");
			} 
			fromdate = ObjectUtil.s2d((String)fromdateObj);
			if(fromdate != null) {
				coditionMap.put("fromdate", fromdate);
				hql.append(" and orderdate >= :fromdate");
			}
			Object todateObj = queryMap.get("todate");
			Date todate = null;
			if(todateObj instanceof Date) {
				Calendar calendar = Calendar.getInstance();
				calendar.setTime((Date)todateObj);
				calendar.set(Calendar.HOUR_OF_DAY, 0);
				calendar.set(Calendar.MINUTE, 0);
				calendar.set(Calendar.SECOND, 0);
				todate = calendar.getTime();
			}else if(todateObj instanceof String) 
				todate = ObjectUtil.s2d((String)todateObj);
			if(todate != null) {
				coditionMap.put("todate", todate);
				hql.append(" and orderdate <= :todate");
			}
			/*String finddateStr = (String)queryMap.get("finddate");
			Date finddate = ObjectUtil.s2d(finddateStr);
			if(finddate != null) {
				coditionMap.put("finddate", todate);
				hql.append(" and finddate = :finddate");
			}*/
			String ordertime = (String)queryMap.get("ordertime");
			if(ordertime != null && ordertime.length() > 0){ 
				coditionMap.put("ordertime", ordertime);
				hql.append(" and ordertime = :ordertime");
			}
			String profeidStr = (String)queryMap.get("profeid");
			Long profeid = ObjectUtil.s2l(profeidStr);
			if(profeid != null && profeid > 0){ 
				coditionMap.put("profeid", profeid);
				hql.append(" and profeid = :profeid");
			}
			String stationidStr = (String)queryMap.get("stationid");
			Long stationid = ObjectUtil.s2l(stationidStr);
			if(stationid != null && stationid > 0){ 
				coditionMap.put("stationid", stationid);
				hql.append(" and stationid = :stationid");
			}
			String companyidStr = (String)queryMap.get("companyid");
			Long companyid = ObjectUtil.s2l(companyidStr);
			if(companyid != null && companyid > 0){ 
				coditionMap.put("companyid", companyid);
				hql.append(" and companyid = :companyid");
			}
			String tmode = (String)queryMap.get("tmode");
			if(tmode != null && tmode.length() > 0){ 
				coditionMap.put("tmode", tmode);
				hql.append(" and tmode = :tmode");
			}
			String status = (String)queryMap.get("status");
			if(status != null && status.length() > 0){ 
				coditionMap.put("status", status);
				hql.append(" and status = :status");
			}
			String cwtidStr = (String)queryMap.get("cwtid");
			Long cwtid = ObjectUtil.s2l(cwtidStr);
			if(cwtid != null && cwtid > 0){ 
				coditionMap.put("cwtid", cwtid);
				hql.append(" and cwtid = :cwtid");
			}
			
		}
		int count = getBaseDao().queryCount("select count(*) " + hql.toString(),coditionMap);
		if (count > 0) {
			if (orderList == null) {
				orderList = new LinkedHashMap<String, Boolean>();
			}
			if (orderList.size() == 0)
				orderList.put("updatedate", false);
			StringBuilder orderString = new StringBuilder("");
			for (Map.Entry<String, Boolean> entry : orderList.entrySet()) {
				String key = entry.getKey();
				key = key.replaceAll("Name$", "");
				boolean value = entry.getValue();
				if (orderString.length() > 0)
					orderString.append(",");
				orderString.append(key);
				if (!value)
					orderString.append(" desc");
			}
			hql.append(" order by ").append(orderString);
			int startIndex = 0;
			int maxSize = 0;
			if (page != null) {
				startIndex = (page.getToPage() - 1) * page.getPageSize();
				maxSize = page.getPageSize();
			}
			list = getBaseDao().list(hql.toString(),coditionMap, startIndex, maxSize);
		}
		
		if (page != null)
			page.setTotalRecord(count);
		return list;
	}
	
	public List<Object[]> list0(Map<String, Object> queryMap,
			PageEntity page, LinkedHashMap<String, Boolean> orderList) {
		List<Object[]> list = new ArrayList<Object[]>();
		
		return list;
	}

	@Override
	@Resource(name = "personOrderDao")
	public void setBaseDao(IPersonOrderDao baseDao) {
		super.setBaseDao(baseDao);
	}

	public IDataDictService getDictservice() {
		return dictservice;
	}
	
	@Resource(name = "dataDictService")
	public void setDictservice(IDataDictService service) {
		this.dictservice = service;
	}

	public ICostService getCostService() {
		return costService;
	}

	@Resource(name = "costService")
	public void setCostService(ICostService costService) {
		this.costService = costService;
	}

	public UserServiceImpl getCsi() {
		return csi;
	}

	@Resource(name = "userServiceImpl")
	public void setCsi(UserServiceImpl csi) {
		this.csi = csi;
	}

	public IPerOrderSetLineService getPerOrderSetLineService() {
		return perOrderSetLineService;
	}

	@Resource(name = "perOrderSetLineService")
	public void setPerOrderSetLineService(IPerOrderSetLineService perOrderSetLineService) {
		this.perOrderSetLineService = perOrderSetLineService;
	}

	public ContractRateServiceImpl getContractRateService() {
		return contractRateService;
	}

	@Resource(name = "contractRateServiceImpl")
	public void setContractRateService(ContractRateServiceImpl contractRateService) {
		this.contractRateService = contractRateService;
	}
}
